package com.weaver.qfengx;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by YeShengtao on 2020/9/27 11:13
 */
public class FileUtils {

    public static List<File> allDir(File file) {
        return allDir(file, -1);
    }

    /**
     * 获取指定目录下的所有的文件目录
     *
     * @param file 指定目录
     * @param dept 递归深度 为-1时 则表示递归所有层级, 1表示获取目录下第一层
     * @return List<File>
     */
    public static List<File> allDir(File file, int dept) {
        if (!file.exists()) {
            throw new RuntimeException("文件目录不存在");
        }
        if (!file.isDirectory()) {
            throw new RuntimeException("file is not directory");
        }
        return recursionFile(file, dept, File::isDirectory);
    }

    public static List<File> allFile(File file) {
        return allFile(file, -1);
    }

    /**
     * 获取指定目录下的所有的文件
     *
     * @param file 指定目录
     * @param dept dept 递归深度 为-1时 则表示递归所有层级, 1表示获取目录下第一层
     * @return List<File>
     */
    public static List<File> allFile(File file, int dept) {
        if (!file.exists()) {
            throw new RuntimeException("文件目录不存在");
        }
        if (!file.isDirectory()) {
            throw new RuntimeException("file is not directory");
        }
        return recursionFile(file, dept, File::isFile);
    }

    public static List<File> recursionFile(File file, int dept, Function<File, Boolean> callable) {
        List<File> list = Lists.newArrayList();
        if (dept == 0) {
            return list;
        }
        List<File> tempList = Arrays.stream(Objects.requireNonNull(file.listFiles())).filter(callable::apply).collect(Collectors.toList());
        int newDept = -1;
        if (dept != -1) {
            newDept = dept - 1;
        }
        for (File tempFile : tempList) {
            list.add(tempFile);
            list.addAll(recursionFile(tempFile, newDept, callable));
        }
        return list;
    }

    public static String getFileExt(String fileName) {
        if (StringUtils.isEmpty(fileName)) return "";
        int extIndex = fileName.lastIndexOf(".");
        if (extIndex == -1) return "";
        return fileName.substring(extIndex + 1);
    }

    public static String realFileName(String fileName) {
        if (StringUtils.isEmpty(fileName)) return fileName;
        int extIndex = fileName.lastIndexOf(".");
        if (extIndex == -1) return fileName;
        return fileName.substring(0, extIndex);
    }

    // 获取文件大小，不区分目录
    public static long size(File file) {
        Assert.notNull(file, "file argument is null !", new Object[0]);
        if (!file.exists())
            throw new IllegalArgumentException(StrUtil.format("File [{}] not exist !", new Object[]{file.getAbsolutePath()}));
        if (file.isFile()) return file.length();

        long size = 0L;
        File[] subFiles = file.listFiles();
        if (ArrayUtils.isEmpty(subFiles)) {
            return size;
        } else {
            for (File sfile : subFiles) {
                size += size(sfile);
            }
            return size;
        }

    }

    @Test
    public void test01() {
        File file = new File("C:\\Users\\Qfeng\\Desktop\\down");
        System.out.println(size(file));
    }

    public static void compressToStream(List<File> fileList, OutputStream outputStream) {
        byte[] buf = new byte[1024 * 8];
        try {
            ZipOutputStream zos = new ZipOutputStream(outputStream);
            for (File file : fileList) {
                FileInputStream fis = new FileInputStream(file);
                zos.putNextEntry(new ZipEntry(file.getName()));
                int len;
                while ((len = fis.read(buf)) > 0) {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                fis.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}